﻿using System;
using System.Collections.Generic;
#if ODIN_INSPECTOR
using Sirenix.OdinInspector;
#endif
using UnityEngine;

namespace JH
{
    /// <summary>
    ///  可序列化的固定长度数组
    /// </summary>
    [Serializable]
    public abstract class SerializableFixedContainer<TContainer, TElem> : ISerializationCallbackReceiver
        where TContainer : IFixedContainer<TElem>
    {
        /// <summary>
        ///  固定长度数组的容器
        /// </summary>
        private TContainer _container;

        /// <summary>
        ///  固定长度数组的容器
        /// </summary>
        public TContainer Container => _container;

        /// <summary>
        ///  最大容量
        /// </summary>
#if ODIN_INSPECTOR
        [LabelText("最大容量")]
#endif
        [SerializeField]
        protected int maxSize;

        /// <summary>
        ///  最大容量
        /// </summary>
#if ODIN_INSPECTOR
        [LabelText("溢出模式")]
#endif
        [SerializeField]
        protected OverflowMode overflowMode = OverflowMode.DiscardOldestAdd;

        /// <summary>
        /// 序列化后的数据
        /// </summary>
#if ODIN_INSPECTOR
        [LabelText("数据")]
#endif
        [SerializeField]
        private List<TElem> serializedData = new();

        /// <summary>
        ///  创建容器实例
        /// </summary>
        protected abstract TContainer GetInstance();

        /// <summary>
        ///  序列化前的操作
        /// </summary>
        public void OnBeforeSerialize()
        {
            var overflow = serializedData.Count - maxSize;

            // 如果超过了最大容量，移除最早的元素
            for (int i = 0; i < overflow; i++) serializedData.RemoveAt(0);
        }

        /// <summary>
        ///  反序列化后的操作
        /// </summary>
        public void OnAfterDeserialize()
        {
            // 把数据从序列化列表中读取到容器中
            maxSize = Mathf.Max(1, maxSize);
            _container = GetInstance();
            foreach (var t in serializedData) _container.Add(t);
        }
    }

    [Serializable]
    public class SerializableFixedArray<T> : SerializableFixedContainer<FixedArray<T>, T>
    {
        protected override FixedArray<T> GetInstance()
        {
            return new FixedArray<T>(maxSize, overflowMode);
        }
    }
  
}